#include <iostream>
#include <vector>
#include <unistd.h>
#include <pthread.h>
#include <string>

// 定义一个全局的条件变量和一个全局的锁
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* routine(void* args)
{
    std::string name = static_cast<const char*>(args);

    while(true)
    {
        pthread_mutex_lock(&mutex);
        // 阻塞等待唤醒，pthread_cond_wait在进行等待的时候是在临界区等待的，所以当前还持有锁，传入锁的意义是当
        // 该线程进行阻塞等待时释放锁，能使别的线程申请该锁
        pthread_cond_wait(&cond, &mutex);
        std::cout << name << std::endl;
        pthread_mutex_unlock(&mutex);
    }

    // delete name;
    return nullptr;
}

#define NUM 5

int main()
{
    std::vector<pthread_t> threads;
    for (int i = 0; i < NUM; i++)
    {
        pthread_t tid;
        char* name = new char[64];
        sprintf(name, "thread-%d", i);
        int n = pthread_create(&tid, nullptr, routine, (void*)name);
        if (n == 0)
        {
            threads.push_back(tid);
        }
        // 这里添加sleep(1)，给每个线程一定时间创建后执行到pthread_cond_wait再创建第二个线程
        sleep(1);
    }

    while(true)
    {
        // 一次唤醒等待中的所有线程
        // std::cout << "一次唤醒所有线程" << std::endl;
        // pthread_cond_broadcast(&cond);
        // 一次唤醒一个线程
        std::cout << "一次唤醒一个线程" << std::endl;
        pthread_cond_signal(&cond);
        sleep(1);
    }

    for (int i = 0; i < NUM; i++)
    {
        pthread_join(threads[i], nullptr);
    }

    return 0;
}

// int main()
// {
//     pthread_t t1, t2;

//     pthread_create(&t1, nullptr, routine, (void*)"thread-1");
//     pthread_create(&t2, nullptr, routine, (void*)"thread-2");

//     sleep(3);

//     while(true)
//     {
//         // 主线程唤醒一个线程
//         // pthread_cond_broadcast(&cond);
//         pthread_cond_signal(&cond);
//         sleep(1);
//     }

//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     return 0;
// }

